/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import java.awt.BorderLayout;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
/**
 *
 * @author Dhruv
 */

//main class
public class PhotoDisplayer implements ActionListener
{
    //main container
    private JFrame frame = new JFrame();
    //label for displaying pictures
    private JLabel photographLabel = new JLabel();
    //toolbar for image icons
    private JToolBar buttonBar = new JToolBar();
    //toolbar for filters
    private JToolBar buttonBar2 = new JToolBar();
    //textfields for each of the filters
    private JTextField textField = new JTextField("Filter by File Name");
    private JTextField textField2 = new JTextField("Filter by Min Size");
    private JTextField textField3 = new JTextField("Filter by Max Size");
    private JTextField textField4 = new JTextField("Date Modified");
    //strings to identify the specific textfields
    static final private String TEXT_ENTERED = "text";
    static final private String TEXT_ENTERED2 = "text2";
    static final private String TEXT_ENTERED3 = "text3";
    static final private String TEXT_ENTERED4 = "text4";
    //all the various buttons
    private JButton button = new JButton(new ImageIcon("search.gif"));
    private JButton button2 = new JButton(new ImageIcon("minus.gif"));
    private JButton button3 = new JButton(new ImageIcon("plus.gif"));
    private JButton button4 = new JButton(new ImageIcon("calendar.gif"));
    private JButton button5 = new JButton(new ImageIcon("refresh.gif"));
    private JButton button6 = new JButton(new ImageIcon("open.gif"));
    //strings to identify the specific buttons
    static final private String SOMETHING_ELSE = "other";
    static final private String SOMETHING_ELSE2 = "other2";
    static final private String SOMETHING_ELSE3 = "other3";
    static final private String SOMETHING_ELSE4 = "other4";
    static final private String SOMETHING_ELSE5 = "other5";
    static final private String SOMETHING_ELSE6 = "other6";
    //which directory was chosen
    private String directory;
    //holds all file objects in the chosen directory
    private File[] listOfFiles;
    //holds all file (image) names in the chosen directory
    private ArrayList<String> imageFileNames = getFileNames();
    //holds all file (image) captions in the chosen directory
    private ArrayList<String> imageCaptions = imageFileNames;
    //scrollpane for images which are bigger than the photographLabel
    private JScrollPane scrollPane;
    //scrollpane if there are a lot of thumnails in the toolbar
    private JScrollPane scrollPane2;
    //for incorrectly loaded images
    private ImageIcon err = new ImageIcon("error.gif");

    //return file (image) names in the chosen directory
    public ArrayList<String> getFileNames()
    {
    	//widget to let users select a directory or file
    	JFileChooser chooser = new JFileChooser();
    	//holds all file (image) names in the chosen directory
    	ArrayList<String> myArr = new ArrayList<String>();

    	//only allow directory selection
    	chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    	//current directory is set
        chooser.setCurrentDirectory(new java.io.File("."));

        //pops up file chooser dialog, user chooses a directory
        int returnVal = chooser.showOpenDialog(null);

        //if the selected option was approved
        if(returnVal == JFileChooser.APPROVE_OPTION)
        {
        	//directory object
        	File folder = chooser.getSelectedFile();
        	//directory string
        	directory = chooser.getSelectedFile() + "\\";
        	//list files objects in the directory object
        	listOfFiles = folder.listFiles();

        	//put all the names of the file objects into myArr
        	for (int i = 0; i < listOfFiles.length; i++)
        	{
     	   		if (listOfFiles[i].isFile())
     	   		{
     	   			myArr.add(directory+listOfFiles[i].getName());
     	   		}//end inner if
        	}//end for
        }//end outer if
        //else no selection was made
        else
        {
        	System.out.println("No Selection ");
        }//end else

        return myArr;
    }//end method

    //main method
    public static void main(String args[])
    {
    	//loads swing elements on the event dispatch thread
        SwingUtilities.invokeLater(new Runnable()
        {
        	//provides thread safety
            public void run()
            {
            	//create a PhotoDisplayer object
            	new PhotoDisplayer();
            }
        });
    }//end method

    //class constructor
    public PhotoDisplayer()
    {
    	//when frame closes, exit
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //sets frame title
        frame.setTitle("Please Select an Image");
        //show frame
        frame.setVisible(true);

        //label for displaying the pictures
        photographLabel.setVerticalTextPosition(JLabel.BOTTOM);
        photographLabel.setHorizontalTextPosition(JLabel.CENTER);
        photographLabel.setHorizontalAlignment(JLabel.CENTER);
        photographLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        //setting attributes for butonBar
        buttonBar.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        buttonBar.setFloatable(false);
        //glue components used to centre the image icons in the toolbar
        buttonBar.add(Box.createGlue());
        buttonBar.add(Box.createGlue());

        //do not allow buttonBar2 to float
        buttonBar2.setFloatable(false);

        //textfield so that users can filter by file name
        textField.setColumns(10);
        textField.addActionListener(this);
        textField.setActionCommand(TEXT_ENTERED);
        //add textfield to toolbar
        buttonBar2.add(textField);

        //button so that users can click to submit file name
        button.setActionCommand(SOMETHING_ELSE);
        button.setToolTipText(".jpg .gif .png recognised only");
        button.addActionListener(this);
        //add button to toolbar
        buttonBar2.add(button);

        //textfield so that users can filter by min file size
        textField2.setColumns(10);
        textField2.addActionListener(this);
        textField2.setActionCommand(TEXT_ENTERED2);
        //add textfield to toolbar
        buttonBar2.add(textField2);

        //button so that users can click to submit min file size
        button2.setActionCommand(SOMETHING_ELSE2);
        button2.setToolTipText("in kilobytes");
        button2.addActionListener(this);
        //add button to toolbar
        buttonBar2.add(button2);

        //textfield so that users can filter by max file size
        textField3.setColumns(10);
        textField3.addActionListener(this);
        textField3.setActionCommand(TEXT_ENTERED3);
        //add textfield to toolbar
        buttonBar2.add(textField3);

        //button so that users can click to submit max file size
        button3.setActionCommand(SOMETHING_ELSE3);
        button3.setToolTipText("in kilobytes");
        button3.addActionListener(this);
        //add button to toolbar
        buttonBar2.add(button3);

        //textfield so that users can filter by date file was modified
        textField4.setColumns(10);
        textField4.addActionListener(this);
        textField4.setActionCommand(TEXT_ENTERED4);
        //add textfield to toolbar
        buttonBar2.add(textField4);

        //button so that users can click to submit date file was modified
        button4.setActionCommand(SOMETHING_ELSE4);
        button4.setToolTipText("DD/MM/YYYY");
        button4.addActionListener(this);
        //add button to toolbar
        buttonBar2.add(button4);

        //button so that users can refresh the thumbnails
        button5.setActionCommand(SOMETHING_ELSE5);
        button5.setToolTipText("reset");
        button5.addActionListener(this);
        //add button to toolbar
        buttonBar2.add(button5);

        //button so that users can reselect directory
        button6.setActionCommand(SOMETHING_ELSE6);
        button6.setToolTipText("select new directory");
        button6.addActionListener(this);
        //add button to toolbar
        buttonBar2.add(button6);

        //add label to the frame, centering it
        frame.add(photographLabel, BorderLayout.CENTER);
        //add toolbar to the frame, in north direction
        frame.add(buttonBar2, BorderLayout.NORTH);
        //add toolbar to the frame, in south direction
        //frame.add(buttonBar, BorderLayout.SOUTH);

        //sets size of frame
        frame.setSize(800, 600);
     	//this centers the frame on the screen
        frame.setLocationRelativeTo(null);

        //start the image loading process
        imageLoad();

        //the scrollpane is used to display images in photographLabel
        scrollPane = new JScrollPane(photographLabel);
        //the scrollpane is used to display images in buttonBar
        scrollPane2 = new JScrollPane(buttonBar);
        //disable vertical scrolling
        scrollPane2.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);

        //add both the scrollpanes to the frame
        frame.add(scrollPane);
        frame.add(scrollPane2, BorderLayout.SOUTH);
    }//end constructor

    //image loading process
    public void imageLoad()
    {
    	//run loop for all the captions of images in the selected directory
    	for (int i = 0; i < imageCaptions.size(); i++)
    	{
    		//create an image icon by createImageIcon method
    		ImageIcon icon = createImageIcon(imageFileNames.get(i),
    				imageCaptions.get(i));
            //DisplayThumb object
    		DisplayThumb display;

    		//if the icon was formed
            if(icon != null)
            {
            	//create an image icon for the thumbnail
            	ImageIcon thumbnailIcon = new ImageIcon(
            			getScaledImage(icon.getImage(), 32, 32));
                //create DisplayThumb object with the given parameters
            	//to constructor
            	display = new DisplayThumb(icon, thumbnailIcon,
            			imageCaptions.get(i), photographLabel, frame);
                //make the thumbnail into a button, passing the display
            	//object as parameter
            	JButton thumbButton = new JButton(display);
            	//add the thumbnail button to the toolbar, while also centering it
                buttonBar.add(thumbButton, buttonBar.getComponentCount() - 1);
            }//end if
            else
            {
            	//the image failed to load, so load a err ImageIcon instead
            	display = new DisplayThumb(err, err,
                		imageCaptions.get(i), photographLabel, frame);
                //make the thumbnail into a button, passing the display
            	//object as parameter
                JButton thumbButton = new JButton(display);
            	//add the thumbnail button to the toolbar, while also centering it
                buttonBar.add(thumbButton, buttonBar.getComponentCount() - 1);
            }//end else
        }//end for
    }//end method

    //creates an image icon
    protected ImageIcon createImageIcon(String path, String description)
    {
    	//only accept .jpg .gif and .png image formats
    	if (path.indexOf(".jpg") >= 0 || path.indexOf(".gif") >= 0
        		|| path.indexOf(".png") >= 0)
    	{
            return new ImageIcon(path, description);
        }//end if
    	else
    	{
    		//file could not be made into an icon
            System.err.println("Error with file: " + path);
            return null;
        }//end else
    }//end method

    //resizes an image
    private Image getScaledImage(Image srcImg, int w, int h)
    {
    	//makes BufferedImage object with 8-bit RGB colour components
        BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        //uses BufferedImage object to render the image
        Graphics2D g2 = resizedImg.createGraphics();
        //renders the srcImg image, scaling it accordingly
        g2.drawImage(srcImg, 0, 0, w, h, null);
        //manually free resources
        g2.dispose();

        return resizedImg;
    }//end method

    //action event on listeners triggers this method
    public void actionPerformed(ActionEvent e)
    {
    	//gets the action command
    	String cmd = e.getActionCommand();

    	//if the relevant button or textfield caused the event
    	if(SOMETHING_ELSE.equals(cmd) || TEXT_ENTERED.equals(cmd))
    	{
    		//get text specifically from textField
    		String t = textField.getText();
    		//make it into file path
    		String text = directory + t;

    		//add all file names to imageFileNames; this is done because
    		//imageFileNames may have changed by other action events
    		for(int i=0 ; i < listOfFiles.length ; i++)
    		{
    			imageFileNames.add(directory+listOfFiles[i].getName());
    		}//end for

    		//if imageFileNames has the text entered
    		if(imageFileNames.contains(text))
    		{
    			//we only want to display that image so we clear all names
    			imageFileNames.clear();
    			//we then add that name
    			imageFileNames.add(text);
    			//update corresponding imageCaptions
    			imageCaptions=imageFileNames;
    			//update the widgets
    			refresh();
    		}//end inner if
    		else
    		{
    			//else display error dialog
    			JOptionPane.showMessageDialog(frame,
    					"Please enter valid filename",
    					"Error",
        			    JOptionPane.ERROR_MESSAGE);
    		}//end else
    	}//end outer if

    	//if the relevant button or textfield caused the event
    	if (SOMETHING_ELSE2.equals(cmd) || TEXT_ENTERED2.equals(cmd))
    	{
    		//get text specifically from textField2
    		String t = textField2.getText();
    		try
    		{
    			//clear imageFileNames so we can add new image names
    			imageFileNames.clear();

    			//for all files
    			for(int i=0 ; i < listOfFiles.length ; i++)
    			{
    				//if the file length is bigger than the input double
    				if(listOfFiles[i].length()/1024.0 > Double.parseDouble(t))
    				{
    					//add file name to imageFileNames
    					imageFileNames.add(directory+listOfFiles[i].getName());
    				}//end inner if
    			}//end for

    			//update corresponding imageCaptions
    			imageCaptions=imageFileNames;
    			//update the widgets
    			refresh();
    		}//end try
    		catch (Exception ex)
    		{
    			//display error dialog
    			JOptionPane.showMessageDialog(frame,
    					"Please input a double",
        			    "Error",
        			    JOptionPane.ERROR_MESSAGE);
    		}//end catch
    	}//end if

    	//if the relevant button or textfield caused the event
    	if (SOMETHING_ELSE3.equals(cmd) || TEXT_ENTERED3.equals(cmd))
    	{
    		//get text specifically from textField3
    		String t = textField3.getText();

    		try
    		{
    			//clear imageFileNames so we can add new image names
    			imageFileNames.clear();

    			//for all files
    			for(int i=0 ; i < listOfFiles.length ; i++)
    			{
    				//if the file length is smaller than the input double
    				if(listOfFiles[i].length()/1024.0 < Double.parseDouble(t))
    				{
    					//add file name to imageFileNames
    					imageFileNames.add(directory+listOfFiles[i].getName());
    				}//end inner if
    			}//end for

    			//update corresponding imageCaptions
    			imageCaptions=imageFileNames;
    			//update the widgets
    			refresh();
    		}//end try
    		catch (Exception ex)
    		{
    			//display error dialog
    			JOptionPane.showMessageDialog(frame,
    					"Please input a double",
        			    "Error",
        			    JOptionPane.ERROR_MESSAGE);
    		}//end catch
    	}//end outer if

    	//if the relevant button or textfield caused the event
    	if (SOMETHING_ELSE4.equals(cmd) || TEXT_ENTERED4.equals(cmd))
    	{
    		//get text specifically from textField4
    		String t = textField4.getText();
    		//clear imageFileNames so we can add new image names
    		imageFileNames.clear();

    		//for all files
    		for(int i=0 ; i < listOfFiles.length ; i++)
    		{
    			//check what date that file was last modified
    			String date = new java.text.SimpleDateFormat("dd/MM/yyyy")
    			.format(new java.util.Date (listOfFiles[i].lastModified()));
    			//if input equals date
    			if(t.equals(date))
    			{
    				//add file name to imageFileNames
    				imageFileNames.add(directory+listOfFiles[i].getName());
    			}//end inner if
    		}//end for

    		//if nothing happened, then the input is invalid
    		if(imageFileNames.size()==0)
    		{
    			//display error dialog
    			JOptionPane.showMessageDialog(frame,
    					"Please enter valid modify date",
        			    "Error",
        			    JOptionPane.ERROR_MESSAGE);
    		}//end inner if
    		else
    		{
    			//update corresponding imageCaptions
    			imageCaptions = imageFileNames;
    			//update the widgets
    			refresh();
    		}//end else
    	}//end outer if

    	//if the relevant button or textfield caused the event
    	if (SOMETHING_ELSE5.equals(cmd))
    	{
    		//clear imageFileNames so we can add new image names
			imageFileNames.clear();

			//add all file names to imageFileNames
    		for(int i=0 ; i < listOfFiles.length ; i++)
    		{
    			imageFileNames.add(directory+listOfFiles[i].getName());
    		}//end for

    		//update corresponding imageCaptions
			imageCaptions = imageFileNames;
			//update the widgets
			refresh();
    	}//end if

    	//if the relevant button or textfield caused the event
    	if (SOMETHING_ELSE6.equals(cmd))
    	{
    		//clear imageFileNames so we can add new image names
			imageFileNames.clear();
			//select new image directory
			imageFileNames = getFileNames();
    		//update corresponding imageCaptions
			imageCaptions = imageFileNames;
			//update the widgets
			refresh();
    	}//end if
    }//end method

    //updates the widgets
    public void refresh()
    {
    	//remove all components from buttonBar
    	buttonBar.removeAll();
    	//glue components used to centre the image icons in the toolbar
    	buttonBar.add(Box.createGlue());
    	buttonBar.add(Box.createGlue());
    	//start the image loading process
    	imageLoad();
    	//repaint buttonBar to reflect changes
    	buttonBar.repaint();
    }//end method
}//end class